1、 GPIO 子系统层次结构
	GPIO 子系统可分为3层，分别是使用者、抽象层、控制器驱动：
	使用者：即使用 GPIO子系统的驱动，它们使用抽象层向上提供的接口
	抽象层：启承上启下作用，向上为使用者提供统一接口，向下提供管理多个 GPIO 控制器驱动的功能
	控制器驱动：用于驱动 GPIO 控制器，它按照抽象层的要求实现相应得到的硬件控制
2、 gpio_devic 对象
	gpio_devic 对象表示一个 GPIO 控制器，其核心成员如下：
	//ID ，表示是系统中的第几个 GPIO 控制器，由系统自动分配
	int id;
	//提供 GPIO 操作函数集合及一些创建 gpio_devic 所需的基本消息
	struct gpio_chip *chip;
	//用于描述 GPIO 的数组，每个 GPIO 都应该有一个结构体
	struct gpio_desc *descs;
	//GPIO 基值
	int base;
	//GPIO 个数
	u16 ngpio;
	//控制器名字
	const char *label;
	//gpio_pin_range 类型的链表，用于描述 GPIO 子系统中的 GPIO 编号与 pinctrl 控制器中的引脚编号的对应关系
	struct list_head pin_ranges;
3、 gpio_chip 对象
	gpio_chip 对象中包含操作 GPIO 的函数，其主要成员如下：
	//请求 GPIO
	int (*request)(struct gpio_chip *chip, unsigned offset);
	//释放 GPIO
	void (*free)(struct gpio_chip *chip, unsigned offset);
	//获取 IO 方向，0输出，1输入
	int (*get_direction)(struct gpio_chip *chip, unsigned offset);
	//设置为输入
	int (*direction_input)(struct gpio_chip *chip, unsigned offset);
	//设置为输出
	int (*direction_output)(struct gpio_chip *chip, unsigned offset, int value);
	//获取 IO 状态
	int (*get)(struct gpio_chip *chip, unsigned offset);
	//设置 IO 状态
	void (*set)(struct gpio_chip *chip, unsigned offset, int value);
	//配置 GPIO
	int (*set_config)(struct gpio_chip *chip, unsigned offset, unsigned long config);
	//对 GPIO 的中断进行映射
	int (*to_irq)(struct gpio_chip *chip, unsigned offset);
	//GPIO 基值，为-1表示由系统分配
	int base;
	//GPIO 个数
	u16 ngpio;
	//控制器名字
	const char *label;
	//GPIO 控制器的设备树节点
	struct device_node *of_node;
	//访问 IO 时是否可能会执行引起休眠的函数，在通过 I2C 或 SPI 访问 GPIO 扩展芯片时必须为 true
	bool can_sleep;
4、 gpio_desc 对象
	gpio_desc 对象用于描述单个 GPIO ，其核心成员如下：
	struct gpio_desc
	//引脚属于哪个 GPIO 控制器
	struct gpio_device *gdev;
	//连接标签
	const char *label;
	//GPIO 名字
	const char *name;
5、 gpio_pin_range 对象
	gpio_pin_range 对象用于描述 GPIO 子系统中的 GPIO 编号与 pinctrl 控制中的引脚编号的对应关系，其核心成
员如下：
	//链表节点，用于构成链表
	struct list_head node;
	//所关联的 pinctrl_dev
	struct pinctrl_dev *pctldev;
	//引脚映射关系
	struct pinctrl_gpio_range range;
	pinctrl_gpio_range 展开后的核心成员如下：
	//名称
	const char *name;
	//ID 号
	unsigned int id;
	//GPIO 子系统中的 GPIO 编号，等于 GPIO控制器的 GPIO 基值加上控制器内的引脚偏移
	unsigned int base;
	//对应的 pinctrl 设备中的引脚编号
	unsigned int pin_base;
	//引脚数量
	unsigned int npins;
	//所对应的 gpio_chip
	struct gpio_chip *gc;
6、 pinctrl 子系统与 GPIO 子系统的关系
	在 pinctrl_dev 中有一个成员 struct list_head gpio_ranges ，它是一个链表，其中包含一系列的 struct 
pinctrl_gpio_range ，用于描述 GPIO 子系统中的 GPIO 编号与 pinctrl 控制器中的引脚编号的对应关系。在驱动开发中
可通过在 GPIO 控制器的设备树节点中添加 gpio-ranges 属性将 pinctrl 子系统与 GPIO 子系统关联到一起，gpio-ranges
属性的格式如下：
	gpio-ranges = <引用关联的 pinctrl 节点  GPIO 控制器的 GPIO 编号  GPIO 编号对应的 pinctrl 引脚号  引脚数>;
如 gpio-ranges = <&pinctrl 0 32 16> 表示此 GPIO 控制器的0号引脚对应 pinctrl 控制器的32号引脚，总共映射16个引
脚，此外如果设备树没有提供 gpio-ranges 属性还可以通过 gpiochip_add_pin_range 等函数进行关联（实际上设备树关联
方式也是在注册过程中通过解析设备树内容，然后调用此函数进行关联的）。
	将 GPIO 子系统与 pinctrl 子系统关联后 GPIO 子系统还不能自动调用 pinctrl 子系统将引脚配置为 GPIO 模式，还
需要实现如下函数：
	a) 在 GPIO 子系统中实现 request 函数，这个函数需要调用 gpiochip_generic_request 函数
	b) 在 GPIO 子系统中实现 free 函数，这个函数需要调用 gpiochip_generic_free 函数
	c) 在 pinctrl 的 pinmux_ops 中实现 gpio_request_enable 或 request 函数，用于将引脚配置为 GPIO 功能
	d) 在 pinctrl 的 pinmux_ops 中实现 gpio_disable_free 或 free 函数，用于实现第 c 步的反操作 [可选]
7、 stm32 的 pinctrl 子系统与 GPIO 子系统关联方法
	在 STM32 提供的驱动中实现了如下操作：
	a) 在设备树中提供 gpio-ranges 属性
	b) 在 GPIO 子系统中实现 request 函数，并调用了 pinctrl_gpio_request 函数（gpiochip_generic_request 也是
采用此函数实现）
	但是在 STM32 的驱动中没有为 pinctrl 的 pinmux_ops 提供 gpio_request_enable 和 request 函数，导致在 GPIO 
子系统中 request 函数不能将引脚配置为 GPIO 模式，因此它在 GPIO 子系统的 direction_input 和 direction_output
中调用了 pinctrl_gpio_direction_input 和 pinctrl_gpio_direction_output 函数来将引脚配置为 GPIO 模式并设置方
向。
8、注册 gpio_devic
	注册：
	int devm_gpiochip_add_data(struct device *dev, struct gpio_chip *chip, void *data)
	int gpiochip_add_data(struct gpio_chip *chip, void *data)
	注销：
	void gpiochip_remove(struct gpio_chip *chip)
